﻿#region [===== Using =====]
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml.Serialization;
using System.Globalization;
#endregion

namespace TPG.SharePoint.Workflow
{
    /// <summary>
    /// Support class for serializing and deserializing workflow data such
    /// as association or task data.
    /// </summary>
    public static class WorkflowDataSerializer
    {
        #region [===== Public methods =====]
        /// <summary>
        /// Serializes an object using the <see cref="BinaryFormatter" /> 
        /// into a Base64 encoded string.
        /// </summary>
        /// <param name="data">The data to serialize.</param>
        /// <typeparam name="TData">The type of data to process.</typeparam>
        /// <returns>A Base64 encoded string containing serialized 
        /// data.</returns>
        public static string SerializeToBase64String<TData>(TData data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(ms, data);
                return Convert.ToBase64String(ms.ToArray());
            }
        }

        /// <summary>
        /// Deserializes an object from a Base64 encoded string 
        /// using the <see cref="BinaryFormatter" />.
        /// </summary>
        /// <param name="data">The Base64 encoded data to deserialize.</param>
        /// <typeparam name="TData">The type of data to process.</typeparam>
        /// <returns>The deserialized object.</returns>
        public static TData DeserializeFromBase64String<TData>(string data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] content = Convert.FromBase64String(data);
                ms.Write(content, 0, content.Length);
                ms.Position = 0;
                BinaryFormatter formatter = new BinaryFormatter();
                return (TData)formatter.Deserialize(ms);
            }
        }

        /// <summary>
        /// Serializes an object using the <see cref="XmlSerializer" /> 
        /// into an XML string.
        /// </summary>
        /// <param name="data">The data to serialize.</param>
        /// <typeparam name="TData">The type of data to process.</typeparam>
        /// <returns>An XML string containing serialized 
        /// data.</returns>
        public static string SerializeToXmlString<TData>(TData data)
        {
            StringBuilder serializedData = new StringBuilder();
            using (StringWriter writer = new StringWriter(serializedData, CultureInfo.InvariantCulture))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(TData));
                serializer.Serialize(writer, data);
            }
            return serializedData.ToString();
        }


        /// <summary>
        /// Deserializes an object from an XML string 
        /// using the <see cref="XmlSerializer" />.
        /// </summary>
        /// <param name="data">The XML data to deserialize.</param>
        /// <typeparam name="TData">The type of data to process.</typeparam>
        /// <returns>The deserialized object.</returns>        
        public static TData DeserializeFromXmlString<TData>(string data)
        {
            using (StringReader reader = new StringReader(data))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(TData));
                return (TData)serializer.Deserialize(reader);
            }
        }
        #endregion
    }
}
